﻿/**

 * Copyright (c) 2015-2016, FastDev 刘强 (fastdev@163.com) & Quincy.

 *

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *      http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */


using OF.Notify.DataHost;
using OF.Notify.DataHost.Cluster;
using OF.Notify.DataHost.Cluster.Entity;
using OF.Notify.Entity;
using OF.Notify.Master;
using OF.Notify.Test.Entity;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OF.Notify.Channel
{
    public class MockNotifyServiceProvider : INotifyServiceProvider
    {
        internal ConcurrentDictionary<short, DataNode> dataNodeDict = new ConcurrentDictionary<short, DataNode>();
        internal ConcurrentDictionary<string, DataNode> dataUrlNodeDict = new ConcurrentDictionary<string, DataNode>();
        public void InitCurrentDataNode(DataHost.Cluster.DataNode dataNodeService)
        {
            dataNodeDict.AddOrUpdate(dataNodeService.Id, dataNodeService, (k, v) => dataNodeService);
            dataUrlNodeDict.AddOrUpdate(dataNodeService.notifyHostUrl, dataNodeService, (k, v) => dataNodeService);
        }

        public DataHost.INotifyService GetNotifyService(Master.DataNodeProxy proxy)
        {
            DataNode node = null;
            if (!dataNodeDict.TryGetValue(proxy.GetId(), out node))
            {
                throw new NotImplementedException("param:" + proxy.GetId() + ",dict:\n" + string.Join("\n", dataNodeDict.Keys));
            }
            return node;
        }

        public INotifyService GetNotifyService(string notifyServiceUrl)
        {
            DataNode node = null;
            if (!dataUrlNodeDict.TryGetValue(notifyServiceUrl, out node))
            {
                throw new NotImplementedException("param:" + notifyServiceUrl + ",dict:\n" + string.Join("\n", dataUrlNodeDict.Keys));
            }
            //Util.LogInfo("GetNotifyService node:" + node.Id);
            return node;
        }

        public void VisitAllNodes(ClusterMaster clusterMaster, byte topicEnum, AllNodesRuntimeData result)
        {
            var nodes = dataNodeDict.Values.ToList();
            foreach (var node in nodes)
            {
                var data = node.GetRuntimeData(new GetRuntimeDataRequest { topicEnum = topicEnum });
                if (data != null)
                {
                    result.NodeRuntimeDataList.Add(data);
                }
            }
            result.NodeCount = nodes.Count;
            result.OnlineNodeCount = clusterMaster.dataNodeProxyDict.Count;
            result.OnLineNodeIds = clusterMaster.dataNodeProxyDict.Keys.ToList();
        }
    }
}
